{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-01-12T13:46:37.380012Z",
     "start_time": "2019-01-12T13:46:35.976721Z"
    },
    "code_folding": [
     48,
     63,
     72,
     83,
     87,
     167,
     174,
     266,
     273,
     283,
     288,
     296
    ],
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "from __future__ import division\n",
    "\n",
    "import os\n",
    "\n",
    "os.system('export LD_LIBRARY_PATH=/usr/local/cuda-8.0/lib64')\n",
    "\n",
    "os.environ['KERAS_BACKEND']='tensorflow'\n",
    "\n",
    "os.environ['PATH']='/usr/local/cuda-8.0/bin'\n",
    "os.environ['LD_LIBRARY_PATH']='/usr/local/cuda-8.0/lib64'\n",
    "\n",
    "import skimage.transform as transform\n",
    "from skimage import img_as_ubyte\n",
    "import tifffile as tif\n",
    "\n",
    "from keras.models import Model\n",
    "from keras.layers import Input, merge, Convolution2D, MaxPooling2D, UpSampling2D, Cropping2D\n",
    "from keras import backend as K\n",
    "import keras\n",
    "from keras.layers.normalization import BatchNormalization\n",
    "from keras.optimizers import Nadam\n",
    "import pandas as pd\n",
    "from keras.backend import binary_crossentropy\n",
    "\n",
    "import datetime\n",
    "import random\n",
    "import threading\n",
    "import argparse\n",
    "\n",
    "from keras.models import model_from_json\n",
    "from keras.callbacks import ModelCheckpoint\n",
    "K.set_image_dim_ordering('tf')\n",
    "\n",
    "import numpy as np\n",
    "from keras.models import load_model\n",
    "\n",
    "img_rows = 1024\n",
    "img_cols = 1024\n",
    "num_channels = 3\n",
    "\n",
    "smooth = 1e-12\n",
    "num_mask_channels = 1\n",
    "\n",
    "\n",
    "def jaccard_coef(y_true, y_pred):\n",
    "    intersection = K.sum(y_true * y_pred, axis=[0, -1, -2])\n",
    "    sum_ = K.sum(y_true + y_pred, axis=[0, -1, -2])\n",
    "\n",
    "    jac = (intersection + smooth) / (sum_ - intersection + smooth)\n",
    "\n",
    "    return K.mean(jac)\n",
    "\n",
    "\n",
    "def jaccard_coef_int(y_true, y_pred):\n",
    "    y_pred_pos = K.round(K.clip(y_pred, 0, 1))\n",
    "\n",
    "    intersection = K.sum(y_true * y_pred_pos, axis=[0, -1, -2])\n",
    "    sum_ = K.sum(y_true + y_pred_pos, axis=[0, -1, -2])\n",
    "\n",
    "    jac = (intersection + smooth) / (sum_ - intersection + smooth)\n",
    "\n",
    "    return K.mean(jac)\n",
    "\n",
    "\n",
    "def jaccard_coef_loss(y_true, y_pred):\n",
    "    return -K.log(jaccard_coef(y_true, y_pred)) + binary_crossentropy(y_pred, y_true)\n",
    "\n",
    "\n",
    "def get_unet0():\n",
    "    inputs = Input((img_rows, img_cols, num_channels))\n",
    "    conv1 = Convolution2D(16, 3, 3, border_mode='same', init='he_uniform', dim_ordering='tf')(inputs)\n",
    "    conv1 = BatchNormalization(mode=0)(conv1)\n",
    "    conv1 = keras.layers.advanced_activations.ELU()(conv1)\n",
    "    conv1 = Convolution2D(16, 3, 3, border_mode='same', init='he_uniform', dim_ordering='tf')(conv1)\n",
    "    conv1 = BatchNormalization(mode=0)(conv1)\n",
    "    conv1 = keras.layers.advanced_activations.ELU()(conv1)\n",
    "    pool1 = MaxPooling2D(dim_ordering='tf', pool_size=(2, 2))(conv1)\n",
    "\n",
    "    conv2 = Convolution2D(32, 3, 3, border_mode='same', init='he_uniform', dim_ordering='tf')(pool1)\n",
    "    conv2 = BatchNormalization(mode=0)(conv2)\n",
    "    conv2 = keras.layers.advanced_activations.ELU()(conv2)\n",
    "    conv2 = Convolution2D(32, 3, 3, border_mode='same', init='he_uniform', dim_ordering='tf')(conv2)\n",
    "    conv2 = BatchNormalization(mode=0)(conv2)\n",
    "    conv2 = keras.layers.advanced_activations.ELU()(conv2)\n",
    "    pool2 = MaxPooling2D(dim_ordering='tf', pool_size=(2, 2))(conv2)\n",
    "\n",
    "    conv3 = Convolution2D(64, 3, 3, border_mode='same', init='he_uniform', dim_ordering='tf')(pool2)\n",
    "    conv3 = BatchNormalization(mode=0)(conv3)\n",
    "    conv3 = keras.layers.advanced_activations.ELU()(conv3)\n",
    "    conv3 = Convolution2D(64, 3, 3, border_mode='same', init='he_uniform', dim_ordering='tf')(conv3)\n",
    "    conv3 = BatchNormalization(mode=0)(conv3)\n",
    "    conv3 = keras.layers.advanced_activations.ELU()(conv3)\n",
    "    pool3 = MaxPooling2D(dim_ordering='tf', pool_size=(2, 2))(conv3)\n",
    "\n",
    "    conv4 = Convolution2D(128, 3, 3, border_mode='same', init='he_uniform', dim_ordering='tf')(pool3)\n",
    "    conv4 = BatchNormalization(mode=0)(conv4)\n",
    "    conv4 = keras.layers.advanced_activations.ELU()(conv4)\n",
    "    conv4 = Convolution2D(128, 3, 3, border_mode='same', init='he_uniform', dim_ordering='tf')(conv4)\n",
    "    conv4 = BatchNormalization(mode=0)(conv4)\n",
    "    conv4 = keras.layers.advanced_activations.ELU()(conv4)\n",
    "    pool4 = MaxPooling2D(dim_ordering='tf', pool_size=(2, 2))(conv4)\n",
    "\n",
    "    conv5 = Convolution2D(256, 3, 3, border_mode='same', init='he_uniform', dim_ordering='tf')(pool4)\n",
    "    conv5 = BatchNormalization(mode=0)(conv5)\n",
    "    conv5 = keras.layers.advanced_activations.ELU()(conv5)\n",
    "    conv5 = Convolution2D(256, 3, 3, border_mode='same', init='he_uniform', dim_ordering='tf')(conv5)\n",
    "    conv5 = BatchNormalization(mode=0)(conv5)\n",
    "    conv5 = keras.layers.advanced_activations.ELU()(conv5)\n",
    "\n",
    "    up6 = merge([UpSampling2D(dim_ordering='tf', size=(2, 2))(conv5), conv4], mode='concat', concat_axis=3)\n",
    "    conv6 = Convolution2D(128, 3, 3, border_mode='same', init='he_uniform', dim_ordering='tf')(up6)\n",
    "    conv6 = BatchNormalization(mode=0)(conv6)\n",
    "    conv6 = keras.layers.advanced_activations.ELU()(conv6)\n",
    "    conv6 = Convolution2D(128, 3, 3, border_mode='same', init='he_uniform', dim_ordering='tf')(conv6)\n",
    "    conv6 = BatchNormalization(mode=0)(conv6)\n",
    "    conv6 = keras.layers.advanced_activations.ELU()(conv6)\n",
    "\n",
    "    up7 = merge([UpSampling2D(dim_ordering='tf', size=(2, 2))(conv6), conv3], mode='concat', concat_axis=3)\n",
    "    conv7 = Convolution2D(64, 3, 3, border_mode='same', init='he_uniform', dim_ordering='tf')(up7)\n",
    "    conv7 = BatchNormalization(mode=0)(conv7)\n",
    "    conv7 = keras.layers.advanced_activations.ELU()(conv7)\n",
    "    conv7 = Convolution2D(64, 3, 3, border_mode='same', init='he_uniform', dim_ordering='tf')(conv7)\n",
    "    conv7 = BatchNormalization(mode=0)(conv7)\n",
    "    conv7 = keras.layers.advanced_activations.ELU()(conv7)\n",
    "\n",
    "    up8 = merge([UpSampling2D(dim_ordering='tf', size=(2, 2))(conv7), conv2], mode='concat', concat_axis=3)\n",
    "    conv8 = Convolution2D(32, 3, 3, border_mode='same', init='he_uniform', dim_ordering='tf')(up8)\n",
    "    conv8 = BatchNormalization(mode=0)(conv8)\n",
    "    conv8 = keras.layers.advanced_activations.ELU()(conv8)\n",
    "    conv8 = Convolution2D(32, 3, 3, border_mode='same', init='he_uniform', dim_ordering='tf')(conv8)\n",
    "    conv8 = BatchNormalization(mode=0)(conv8)\n",
    "    conv8 = keras.layers.advanced_activations.ELU()(conv8)\n",
    "\n",
    "    up9 = merge([UpSampling2D(dim_ordering='tf', size=(2, 2))(conv8), conv1], mode='concat', concat_axis=3)\n",
    "    conv9 = Convolution2D(16, 3, 3, border_mode='same', init='he_uniform', dim_ordering='tf')(up9)\n",
    "    conv9 = BatchNormalization(mode=0)(conv9)\n",
    "    conv9 = keras.layers.advanced_activations.ELU()(conv9)\n",
    "    conv9 = Convolution2D(16, 3, 3, border_mode='same', init='he_uniform', dim_ordering='tf')(conv9)\n",
    "    crop9 = Cropping2D(cropping=((12, 12), (12, 12)), dim_ordering='tf')(conv9)\n",
    "    conv9 = BatchNormalization(mode=0)(crop9)\n",
    "    conv9 = keras.layers.advanced_activations.ELU()(conv9)\n",
    "    conv10 = Convolution2D(num_mask_channels, 1, 1, activation='sigmoid', dim_ordering='tf')(conv9)\n",
    "\n",
    "    model = Model(input=inputs, output=conv10)\n",
    "\n",
    "    return model\n",
    "\n",
    "\n",
    "def flip_axis(x, axis):\n",
    "    x = np.asarray(x).swapaxes(axis, 0)\n",
    "    x = x[::-1, ...]\n",
    "    x = x.swapaxes(0, axis)\n",
    "    return x\n",
    "\n",
    "\n",
    "def form_batch(X, y, batch_size):\n",
    "    X_batch = np.zeros((batch_size, num_channels, img_rows, img_cols))\n",
    "    y_batch = np.zeros((batch_size, num_mask_channels, img_rows, img_cols))\n",
    "    X_height = X.shape[2]\n",
    "    X_width = X.shape[3]\n",
    "\n",
    "    for i in range(batch_size):\n",
    "        random_width = random.randint(0, X_width - img_cols - 1)\n",
    "        random_height = random.randint(0, X_height - img_rows - 1)\n",
    "\n",
    "        random_image = random.randint(0, X.shape[0] - 1)\n",
    "\n",
    "        y_batch[i] = y[random_image, :, random_height: random_height + img_rows, random_width: random_width + img_cols]\n",
    "        X_batch[i] = np.array(X[random_image, :, random_height: random_height + img_rows, random_width: random_width + img_cols])\n",
    "    return X_batch, y_batch\n",
    "\n",
    "\n",
    "class threadsafe_iter:\n",
    "    \"\"\"Takes an iterator/generator and makes it thread-safe by\n",
    "    serializing call to the `next` method of given iterator/generator.\n",
    "    \"\"\"\n",
    "    def __init__(self, it):\n",
    "        self.it = it\n",
    "        self.lock = threading.Lock()\n",
    "\n",
    "    def __iter__(self):\n",
    "        return self\n",
    "\n",
    "    def next(self):\n",
    "        with self.lock:\n",
    "            return self.it.next()\n",
    "\n",
    "\n",
    "def threadsafe_generator(f):\n",
    "    \"\"\"A decorator that takes a generator function and makes it thread-safe.\n",
    "    \"\"\"\n",
    "    def g(*a, **kw):\n",
    "        return threadsafe_iter(f(*a, **kw))\n",
    "    return g\n",
    "\n",
    "\n",
    "@threadsafe_generator\n",
    "def batch_generator(root, index, RGB, batch_size=32, horizontal_flip=True, vertical_flip=True, swap_axis=True, rotate=True):\n",
    "    \"\"\" Batch generator for train, validation and test\n",
    "\n",
    "    :param root: data directory name\n",
    "    :param index: index of data\n",
    "    :param RGB: RGB for pixel of the mask category\n",
    "    :param batch_size: batch size\n",
    "    :return: yield every image batch and mask batch\n",
    "    \"\"\"\n",
    "    length = len(index)\n",
    "    while True:\n",
    "        for i in range(batch_size, length, batch_size):\n",
    "            img_batch, mask_batch = [], []\n",
    "            for idx in range(i - batch_size, i):\n",
    "                img_path = os.path.join(root, '%d.tif' % index[idx])\n",
    "                gt_path = os.path.join(root, '%d_mask.tif' % index[idx])\n",
    "\n",
    "                img = tif.imread(img_path).astype(np.float16)\n",
    "                for c in range(num_channels):\n",
    "                    img[:,:,c] = (img[:,:,c] - img[:,:,c].min()) / (img[:,:,c].max() - img[:,:,c].min()) # normalization\n",
    "\n",
    "                gt = img_as_ubyte(tif.imread(gt_path))  # with regard to the type of gt img\n",
    "                gt = _convert_mask(gt, RGB)\n",
    "\n",
    "                if horizontal_flip:\n",
    "                    if np.random.random() < 0.5:\n",
    "                        img = flip_axis(img, 0)\n",
    "                        gt = flip_axis(gt, 0)\n",
    "\n",
    "                if vertical_flip:\n",
    "                    if np.random.random() < 0.5:\n",
    "                        img = flip_axis(img, 1)\n",
    "                        gt = flip_axis(gt, 1)\n",
    "\n",
    "                if swap_axis:\n",
    "                    if np.random.random() < 0.5:\n",
    "                        img = img.swapaxes(0, 1)\n",
    "                        gt = gt.swapaxes(0, 1)\n",
    "\n",
    "                if rotate:\n",
    "                    if np.random.random() < 0.5:\n",
    "                        img = transform.rotate(img, 90)\n",
    "                        gt = transform.rotate(gt, 90)\n",
    "\n",
    "                img_batch.append(img)\n",
    "                mask_batch.append(gt)\n",
    "\n",
    "            yield (np.array(img_batch), np.array(mask_batch))\n",
    "\n",
    "\n",
    "def _convert_mask(img, RGB):\n",
    "    #R, G, B = RGB\n",
    "    #img = (img[..., 0] == R) & (img[..., 1] == G) & (img[..., 2] == B)\n",
    "    img = img[..., np.newaxis].astype(np.float16)[12:1012, 12:1012, :]\n",
    "    return img\n",
    "\n",
    "\n",
    "def save_model(model, cross):\n",
    "    json_string = model.to_json()\n",
    "    if not os.path.isdir('cache'):\n",
    "        os.mkdir('cache')\n",
    "    json_name = 'architecture_' + cross + '.json'\n",
    "    weight_name = 'model_weights_' + cross + '.h5'\n",
    "    open(os.path.join('cache', json_name), 'w').write(json_string)\n",
    "    model.save_weights(os.path.join('cache', weight_name), overwrite=True)\n",
    "\n",
    "\n",
    "def save_history(history, suffix):\n",
    "    filename = 'history/history_' + suffix + '.csv'\n",
    "    pd.DataFrame(history.history).to_csv(filename, index=False)\n",
    "\n",
    "\n",
    "def read_model(cross=''):\n",
    "    json_name = 'architecture_' + cross + '.json'\n",
    "    weight_name = 'model_weights_' + cross + '.h5'\n",
    "    model = model_from_json(open(os.path.join('../src/cache', json_name)).read())\n",
    "    model.load_weights(os.path.join('../src/cache', weight_name))\n",
    "    return model\n",
    "\n",
    "\n",
    "def split_dataset(root):\n",
    "    \"\"\" split the index of train, validation, test data by 8:1:1 randomly\n",
    "        data: named from 0 to n as n.tif\n",
    "        label: named from 0 to n as n_mask.tif\n",
    "\n",
    "    :param root: the root path of the dataset\n",
    "    :return: tuple of indices of (train, validation, test)\n",
    "    \"\"\"\n",
    "    for fn in ['train.txt', 'validation.txt', 'test.txt']:\n",
    "        path = os.path.join(root, fn)\n",
    "        if os.path.exists(path):\n",
    "            os.remove(path)\n",
    "\n",
    "    length = int(len(os.listdir(root)) / 2)\n",
    "    print 'num of total images:', length\n",
    "    indices = np.random.permutation(length)\n",
    "    return indices[:int(0.8*length)], \\\n",
    "           indices[int(0.8*length): int(0.9*length)], \\\n",
    "           indices[int(0.9*length):]\n",
    "\n",
    "\n",
    "def save_idx(train, validation, test, root):\n",
    "    np.savetxt(os.path.join(root, 'train.txt'), train, fmt='%d', delimiter=' ')\n",
    "    np.savetxt(os.path.join(root, 'validation.txt'), validation, fmt='%d', delimiter=' ')\n",
    "    np.savetxt(os.path.join(root, 'test.txt'), test, fmt='%d', delimiter=' ')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-01-12T14:52:21.882745Z",
     "start_time": "2019-01-12T14:07:05.071241Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "('num of total img:', 7301)\n",
      "[2019-01-12 22:07:05.141788] Creating and compiling model...\n",
      "Epoch 1/8\n",
      "5836/5840 [============================>.] - ETA: 1s - loss: 1.5314 - binary_crossentropy: 0.3066 - jaccard_coef_int: 0.3715 - binary_accuracy: 0.9057"
     ]
    },
    {
     "ename": "ImportError",
     "evalue": "No module named h5py",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mImportError\u001b[0m                               Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-19-e5686f401153>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m     78\u001b[0m     \u001b[0mnb_val_samples\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvalidation\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0mbatch_size\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0mbatch_size\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     79\u001b[0m     \u001b[0mcallbacks\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mcallbacks\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 80\u001b[0;31m     \u001b[0mnb_worker\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m8\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     81\u001b[0m )\n",
      "\u001b[0;32m/home/yaoxin/program/anaconda3/envs/orbita27/lib/python2.7/site-packages/keras/engine/training.pyc\u001b[0m in \u001b[0;36mfit_generator\u001b[0;34m(self, generator, samples_per_epoch, nb_epoch, verbose, callbacks, validation_data, nb_val_samples, class_weight, max_q_size, nb_worker, pickle_safe, initial_epoch)\u001b[0m\n\u001b[1;32m   1598\u001b[0m                             \u001b[0mepoch_logs\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'val_'\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0ml\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mo\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1599\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1600\u001b[0;31m                 \u001b[0mcallbacks\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mon_epoch_end\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mepoch\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mepoch_logs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   1601\u001b[0m                 \u001b[0mepoch\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1602\u001b[0m                 \u001b[0;32mif\u001b[0m \u001b[0mcallback_model\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstop_training\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/home/yaoxin/program/anaconda3/envs/orbita27/lib/python2.7/site-packages/keras/callbacks.pyc\u001b[0m in \u001b[0;36mon_epoch_end\u001b[0;34m(self, epoch, logs)\u001b[0m\n\u001b[1;32m     74\u001b[0m         \u001b[0mlogs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlogs\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     75\u001b[0m         \u001b[0;32mfor\u001b[0m \u001b[0mcallback\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcallbacks\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 76\u001b[0;31m             \u001b[0mcallback\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mon_epoch_end\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mepoch\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlogs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     77\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     78\u001b[0m     \u001b[0;32mdef\u001b[0m \u001b[0mon_batch_begin\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mbatch\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlogs\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mNone\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/home/yaoxin/program/anaconda3/envs/orbita27/lib/python2.7/site-packages/keras/callbacks.pyc\u001b[0m in \u001b[0;36mon_epoch_end\u001b[0;34m(self, epoch, logs)\u001b[0m\n\u001b[1;32m    382\u001b[0m                     \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmodel\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msave_weights\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfilepath\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0moverwrite\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mTrue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    383\u001b[0m                 \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 384\u001b[0;31m                     \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmodel\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msave\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfilepath\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0moverwrite\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mTrue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    385\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    386\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/home/yaoxin/program/anaconda3/envs/orbita27/lib/python2.7/site-packages/keras/engine/topology.pyc\u001b[0m in \u001b[0;36msave\u001b[0;34m(self, filepath, overwrite)\u001b[0m\n\u001b[1;32m   2628\u001b[0m         \"\"\"\n\u001b[1;32m   2629\u001b[0m         \u001b[0;32mfrom\u001b[0m \u001b[0;34m.\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmodels\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0msave_model\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2630\u001b[0;31m         \u001b[0msave_model\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfilepath\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0moverwrite\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   2631\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   2632\u001b[0m     \u001b[0;32mdef\u001b[0m \u001b[0msave_weights\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfilepath\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0moverwrite\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mTrue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/home/yaoxin/program/anaconda3/envs/orbita27/lib/python2.7/site-packages/keras/models.pyc\u001b[0m in \u001b[0;36msave_model\u001b[0;34m(model, filepath, overwrite)\u001b[0m\n\u001b[1;32m     37\u001b[0m         \u001b[0;32mraise\u001b[0m \u001b[0mTypeError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Not JSON Serializable:'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mobj\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     38\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 39\u001b[0;31m     \u001b[0;32mimport\u001b[0m \u001b[0mh5py\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     40\u001b[0m     \u001b[0;32mfrom\u001b[0m \u001b[0mkeras\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0m__version__\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mkeras_version\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     41\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mImportError\u001b[0m: No module named h5py"
     ]
    }
   ],
   "source": [
    "now = datetime.datetime.now()\n",
    "root = '../data/Building'\n",
    "mask_channel = 1\n",
    "batch_size = 4\n",
    "nb_epoch = 8\n",
    "category = 3 # building\n",
    "resume = 0\n",
    "resume_path = ''\n",
    "\n",
    "class_names = {\n",
    "    0: 'Airplane',\n",
    "    1: 'Airport',\n",
    "    2: 'Baresoil',\n",
    "    3: 'Building',\n",
    "    4: 'Farmland',\n",
    "    5: 'Road',\n",
    "    6: 'Vegetation',\n",
    "    7: 'Water'\n",
    "}\n",
    "\n",
    "category_code = {\n",
    "    0: [255, 255, 255],\n",
    "    1: [255, 255, 0],\n",
    "    2: [0, 0, 0],\n",
    "    3: [0, 0, 255],\n",
    "    4: [0, 255, 255],\n",
    "    5: [255, 0, 255],\n",
    "    6: [0, 255, 0],\n",
    "    7: [255, 0, 0]\n",
    "}\n",
    "\n",
    "RGB = category_code[category]\n",
    "\n",
    "train, validation, test = split_dataset(root)\n",
    "\n",
    "print('[{}] Creating and compiling model...'.format(str(datetime.datetime.now())))\n",
    "\n",
    "weight_path = \"../checkpoints/%d%s\" % (category, class_names[category])\n",
    "\n",
    "if not os.path.exists(weight_path):\n",
    "    os.makedirs(weight_path)\n",
    "weight_path = os.path.join(weight_path, 'weights.{epoch:02d}-{val_loss:.2f}.hdf5')\n",
    "callbacks = [\n",
    "    ModelCheckpoint(\n",
    "        filepath=weight_path,\n",
    "        monitor='val_loss',\n",
    "        verbose=0,\n",
    "        save_best_only=False,\n",
    "        save_weights_only=False,\n",
    "        mode='auto',\n",
    "        period=1\n",
    "    )\n",
    "]\n",
    "\n",
    "if resume:\n",
    "    model = load_model(\n",
    "        resume_path,\n",
    "        custom_objects={\n",
    "            u'jaccard_coef_loss': jaccard_coef_loss,\n",
    "            u'jaccard_coef_int': jaccard_coef_int\n",
    "        })\n",
    "\n",
    "else:\n",
    "    model = get_unet0()\n",
    "\n",
    "    model.compile(\n",
    "        optimizer=Nadam(lr=1e-1),\n",
    "        loss=jaccard_coef_loss,\n",
    "        metrics=['binary_crossentropy', jaccard_coef_int, 'binary_accuracy']\n",
    "    )\n",
    "\n",
    "model.fit_generator(\n",
    "    batch_generator(root, train, RGB, batch_size),\n",
    "    validation_data=batch_generator(root, validation, RGB, batch_size),\n",
    "    nb_epoch=nb_epoch,\n",
    "    verbose=1,\n",
    "    samples_per_epoch=int(len(train) / batch_size)*batch_size,\n",
    "    nb_val_samples=int(len(validation) / batch_size)*batch_size,\n",
    "    callbacks=callbacks,\n",
    "    nb_worker=8\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "orbita27",
   "language": "python",
   "name": "orbita27"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.15"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
